package com.example.othree.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.othree.common.R;
import com.example.othree.entity.Drone;
import com.example.othree.entity.DroneCount;
import com.example.othree.mapper.DroneCountMapper;
import com.example.othree.mapper.DroneMapper;
import com.example.othree.service.DroneManagementService;
import com.example.othree.service.DroneService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.time.format.DateTimeParseException;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/api")
public class DroneController {
    @Autowired
    DroneService droneService;
    // 操作`drone_observation_data数据表，写完记得删除这一行

    @Autowired
    DroneManagementService droneManagementService;
    @Autowired
    private DroneCountMapper droneCountMapper;

    @ApiOperation("获取无人机飞行次数数据")
    @GetMapping("/drone-info")
    // TODO 通过站点（衡水、饶阳）参数，获取无人机飞行日期和时刻汇总数据。
    //  只返回指定站点的所有飞行日期和时刻列表，不返回观测数据。

    public R droneInfo(@RequestParam("equipmentName") String equipmentName) {
        List<DroneCount> droneList;
        try{
            droneList = droneService.toFindByEquipmentName(equipmentName);

            List<Integer> ids = droneList.stream().map(DroneCount::getId).collect(Collectors.toList());

            if (!ids.isEmpty()) {
                // 批量查询每个count_id的最新记录
                QueryWrapper<Drone> droneQueryWrapper = new QueryWrapper<>();
                droneQueryWrapper.in("count_id", ids);
                droneQueryWrapper.groupBy("count_id");
                droneQueryWrapper.select("count_id, MIN(detection_time) as min_time");

                List<Map<String, Object>> minTimes = droneManagementService.listMaps(droneQueryWrapper);

                // 转换为Map方便查找
                Map<Integer, Date> idToMaxTime = minTimes.stream()
                        .collect(Collectors.toMap(
                                map -> (Integer)map.get("count_id"),
                                map -> (Date)map.get("min_time")
                        ));

                // 设置开始时间
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
                for (DroneCount droneCount : droneList) {
                    Date maxTime = idToMaxTime.get(droneCount.getId());
                    if (maxTime != null) {
                        droneCount.setStartTime(formatter.format(maxTime));
                    }
                }
            }
        } catch (DataAccessException e){
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e){
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

        // 需要加上指定站点总的飞行次数
        Integer drone_count = droneService.toFindCountByEquipmentName(equipmentName); //Tao Add

        return R.ok().data("drone_info", droneList).data("drone_count", drone_count);
//        return R.ok().data("drone_info", droneList);
    }

    @ApiOperation("获取某个时间段内无人机观测数据")
    @GetMapping("/drone-data")
    // TODO 该接口根据用户指定的站点、查询时间（起始和结束时间）及是否订正参数，
    //  返回符合条件的无人机观测数据，支持分页功能。

    public R droneData(@RequestParam("equipmentName") String equipmentName,
                       @RequestParam("startTime") String startTim, @RequestParam("endTime") String endTime,
                       @RequestParam(value = "isCorrected", defaultValue = "false") Boolean isCorrected,
                       @RequestParam(value = "page", defaultValue = "1") int page,
                       @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        Map droneData;
        try{
            droneData = droneService.toFindByNameAndDate(equipmentName, startTim, endTime, isCorrected, page, pageSize);
        } catch (DataAccessException e){
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e){
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

        return R.ok().data("droneDate", droneData);
    }

    @ApiOperation("获取无人机某次飞行的观测数据")
    @GetMapping("/drone-data-fixed")
    // TODO 该接口根据站点、飞行时间返回该站点该次飞行监测到的所有订正后数据（不需要分页）。

    public R droneDataFixed(@RequestParam("equipmentName") String equipmentName,
                            @RequestParam("time") String time) {
//        ArrayList<Map> droneList;
//        try{
//            // 需要获取多个时间的数据
//            droneList = droneService.toFindDataFixed(equipmentName, time);
//        } catch (DataAccessException e){
//            e.printStackTrace();
//            return R.error().message("数据库访问出错");
//        } catch (Exception e){
//            e.printStackTrace();
//            return R.error().message("出现了未知错误");
//        }
//
//        return R.ok().data("drone_info", droneList);
        // 根据设备名和时间查某次飞行的数据
        QueryWrapper<DroneCount> droneCountQueryWrapper = new QueryWrapper<>();
        droneCountQueryWrapper.eq("equipment_name", equipmentName);
        droneCountQueryWrapper.eq("start_time", time);
        Integer id;
        try {
            id = droneService.getOne(droneCountQueryWrapper).getId();
        } catch (Exception e) {
            return R.error().message("输入起始时间有误");
        }

        ArrayList<Drone> list = droneManagementService.getDataById(id);
        //o3改大小写呢

        return R.ok().data("drone_info", list);
    }

    @ApiOperation("获取最近一次飞行两个站点的数据")
    @GetMapping("/drone-data-recent")
    public R droneDataRecent() {
        // 获取最近两次飞行的时间
        ArrayList<String> dates = droneService.toFindRecentFly();
        // 假设一次飞行是一个小时
        String neiqiu_start = dates.get(0);
        String raoyang_start = dates.get(1);

        Map droneData1;
        try{
            droneData1 = droneService.toFindByNameAndDate("内丘县气象站", neiqiu_start, addOneHour(neiqiu_start), true, 0, 500);
        } catch (DataAccessException e){
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e){
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

        Map droneData2;
        try{
            droneData2 = droneService.toFindByNameAndDate("饶阳县气象站", raoyang_start, addOneHour(raoyang_start), true, 0, 500);
        } catch (DataAccessException e){
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e){
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

        return R.ok().data("neiqiu", droneData1).data("raoyang", droneData2);
    }



    // 封装的函数：加一小时
    public String addOneHour(String dateTimeStr) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");

        // 将字符串解析为日期对象
        Date date = sdf.parse(dateTimeStr);

        // 使用 Calendar 增加一个小时
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 1);

        // 获取加一小时后的日期
        Date newDate = calendar.getTime();

        // 格式化输出并返回
        return sdf.format(newDate);
    }

    // add
    @ApiOperation("获取无人机某次飞行的观测数据")
    @GetMapping("/drone-data-fixed-range")
    // TODO 该接口根据站点、飞行时间返回该站点该次飞行监测到的所有订正后数据（不需要分页）。

    public R droneDataFixedRange(@RequestParam("equipmentName") String equipmentName,
                            @RequestParam("time") String time) {

        // 根据设备名和时间查某次飞行的数据
        QueryWrapper<DroneCount> droneCountQueryWrapper = new QueryWrapper<>();
        droneCountQueryWrapper.eq("equipment_name", equipmentName);
        droneCountQueryWrapper.eq("start_time", time);
        Integer id;
        try {
            id = droneService.getOne(droneCountQueryWrapper).getId();
        } catch (Exception e) {
            return R.error().message("输入起始时间有误");
        }

        ArrayList<Drone> list = droneManagementService.getDataById(id);
        return R.ok().data("drone_info", list);
    }

    @ApiOperation("上传文件导入")
    @PostMapping("/import")
    public R importData(@RequestParam("file") MultipartFile file) {
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {

            // 1. 解析CSV（自动处理列名）
            CSVParser parser = CSVParser.parse(reader, CSVFormat.DEFAULT
                    .withFirstRecordAsHeader()
                    .withIgnoreHeaderCase()
                    .withTrim());

            // 2. 处理每行数据
            for (CSVRecord record : parser) {
                Drone data = new Drone();

                // 基础信息（直接使用列名）
                data.setEquipmentName(record.get(cleanColumnName("设备名称")));
                data.setEquipmentNumber(record.get("设备编号"));

                // 监测时间（兼容两种格式）
                String timeStr = record.get("监测时间").trim();
                try {
                    LocalDateTime dateTime = LocalDateTime.parse(timeStr,
                            DateTimeFormatter.ofPattern("yyyy/M/d H:mm:ss"));
                    data.setDetectionTime(Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant()));
                } catch (Exception e) {
                    LocalDateTime dateTime = LocalDateTime.parse(timeStr,
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    data.setDetectionTime(Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant()));
                }

                // 数值型数据（带默认值）
                data.setLon(safeParseDouble(record.get("经度")));
                data.setLat(safeParseDouble(record.get("纬度")));
                data.setElevation(safeParseDouble(
                        record.isMapped("海拔") ? record.get("海拔") : record.get("高度")
                ));
                data.setTemp(safeParseDouble(record.get("温度")));
                data.setPm1_0((int)safeParseDouble(record.get("PM1.0")));
                data.setPm2_5((int)safeParseDouble(record.get("PM2.5")));
                data.setPm10((int)safeParseDouble(record.get("PM10")));
                data.setHumidity(safeParseDouble(record.get("湿度")));
                data.setO3(safeParseDouble(record.get("臭氧")));

                droneManagementService.save(data);
            }

            return R.ok();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return R.error();
        }
    }
    private String cleanColumnName(String columnName) {
        return "\uFEFF" + columnName;  // 主动添加BOM字符匹配
    }

    // 安全转换数字（避免报错）
    private double safeParseDouble(String value) {
        try {
            return Double.parseDouble(value);
        } catch (Exception e) {
            return 0.0;
        }
    }
//    public R importData(@RequestParam("file") MultipartFile file) {
//        // 读csv
//        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
//            // 使用 Apache Commons CSV 解析
//            CSVParser parser = CSVParser.parse(reader, CSVFormat.DEFAULT
//                    .withHeader("设备名称", "设备编号", "监测时间", "经度", "纬度", "高度", "温度", "PM1.0", "PM2.5", "PM10", "湿度", "臭氧")
//                    .withSkipHeaderRecord());
//
//            for (CSVRecord record : parser) {
//                Drone data = new Drone();
//                 data.setEquipmentName(record.get("设备名称"));
////                data.setEquipmentName("饶阳县气象站");
//                data.setEquipmentNumber(record.get("设备编号"));
//                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d HH:mm");
//
//                // 解析字符串为 LocalDateTime
//                System.out.println(record.get("监测时间"));
//                LocalDateTime localDateTime = LocalDateTime.parse(record.get("监测时间"), formatter);
//                // 将 LocalDateTime 转换为 java.util.Date
//                Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
//
//                data.setDetectionTime(date);
//                data.setLon(Double.parseDouble(record.get("经度")));
//                data.setLat(Double.parseDouble(record.get("纬度")));
//                data.setElevation(Double.parseDouble(record.get("高度")));
//                data.setTemp(Double.parseDouble(record.get("温度")));
//                data.setPm1_0((int) Double.parseDouble(record.get("PM1.0")));
//                data.setPm2_5((int) Double.parseDouble(record.get("PM2.5")));
//                data.setPm10((int) Double.parseDouble(record.get("PM10")));
//                data.setHumidity(Double.parseDouble(record.get("湿度")));
//                data.setO3(Double.parseDouble(record.get("臭氧")));
//
//                droneManagementService.save(data);
//
//
//            }
//        } catch (Exception e) {
//            System.out.println(e.getMessage());
//            return R.error();
//        }
//        return R.ok();
//    }

    @ApiOperation("添加无人机drone-count数据")
    @PostMapping("/create")
    public R create(@RequestBody DroneCount droneCount) {
        try {
            // 1. 插入主记录
            droneCountMapper.addDroneCount(droneCount);
            Integer countId = droneCount.getId();

            if (countId == null) {
                throw new RuntimeException("插入失败，未获取到自增ID");
            }

            // 2. 准备时间模式（假设startTime是LocalDateTime类型）
            String startTimeStr = droneCount.getStartTime();
            String endTimeStr = droneCount.getEndTime();
            LocalDateTime startTime = LocalDateTime.parse(
                    startTimeStr,
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
            );
            LocalDateTime endTime = LocalDateTime.parse(
                    endTimeStr,
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
            );


            // 格式化为 "yyyy-MM-dd HH%"
            String timePattern = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH")) + "%";
            String timePattern2 = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH")) + "%";

            // 3. 更新关联数据
            droneCountMapper.updateDrone(countId, timePattern,timePattern2, droneCount.getEquipmentName());

            return R.ok();
        } catch (Exception e) {
            // 发生异常时事务会回滚
            System.out.println(e.getMessage());
            return R.error( );
        }
    }

//    private void add_count(Integer countId,String startTime,String equipmentName) {
//        droneCountMapper.updateDrone(countId,startTime,equipmentName);
//    }

}
